﻿using DTcms.Common;
using DTcms.Model;
using DTcms.Web.Mvc.Areas.Admin.Controllers;
using DTcms.Web.Mvc.UI;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace DTcms.Web.Mvc.Controllers
{
    public class Upload_AjaxController : UnitController
    {
        /// <summary>
        /// Api核心事务
        /// </summary>
        private BaseApi _service = new BaseApi();

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
        }

        public JsonResult Action()
        {
            //取得处事类型
            string action = DTRequest.GetQueryString("action");
            switch (action)
            {
                #region UEditor
                case "config": //编辑器配置
                    return EditorConfig();
                case "uploadimage": //编辑器上传图片
                    return EditorUploadImage();
                case "uploadvideo": //编辑器上传视频
                    return EditorUploadVideo();
                case "uploadfile": //编辑器上传附件
                    return EditorUploadFile();
                case "uploadscrawl": //编辑器上传涂鸦
                    return EditorUploadScrawl();
                case "listimage": //编辑器浏览图片
                    return EditorListImage();
                case "listfile": //编辑器浏览文件
                    return EditorListFile();
                case "catchimage": //编辑器远程抓取图片
                    return EditorCatchImage();
                #endregion
                default: //普通上传
                    return UpLoadFile();
            }
        }

        #region 上传文件处理
        public JsonResult UpLoadFile()
        {
            string _delfile = DTRequest.GetString("DelFilePath").TrimStart(','); //要删除的文件
            string fileName = DTRequest.GetString("name"); //文件名

            byte[] byteData = FileHelper.ConvertStreamToByteBuffer(Request.InputStream); //获取文件流
            if (byteData.Length == 0)
            {
                return Json(new { status = 0, msg = "请选择要上传文件！" });
            }

            bool isChunk = Utils.StrToBool(DTRequest.GetQueryString("ischunk"), false); //默认不分片上传
            bool isWater = false; //默认不打水印
            bool isThumbnail = false; //默认不生成缩略图
            bool isCompress = true;  //启用图片压缩
            bool isCover = false;  //是否为封面（频道专用）
            int _channel_id = DTRequest.GetQueryInt("channel");  //频道
            //int _width = DTRequest.GetQueryInt("width");  //强制图片宽度
            //int _height = DTRequest.GetQueryInt("height");  //强制图片高度
            string upType = DTRequest.GetQueryString("uptype");  //上传类型
            #region 判断是否是图片 图片不采用分片
            bool fileExt = false;
            string _fileExt = Path.GetExtension(fileName).Trim('.').ToLower();//判断文件上传类型
            ArrayList al = new ArrayList();
            al.Add("bmp");
            al.Add("jpeg");
            al.Add("jpg");
            al.Add("png");
            if (al.Contains(_fileExt.ToLower()))
            {
                fileExt = true;
            }
            if (fileExt)
            {
                isChunk = false;
            }
            #endregion
            UpLoad upLoad = new UpLoad();
            if (isChunk)//分片
            {
                int chunk = DTRequest.GetQueryInt("chunk");//当前分片在上传分片中的顺序（从0开始）
                string guid = DTRequest.GetQueryString("guid");
                return upLoad.FileSaveAs(upType, byteData, fileName, guid, chunk, out string fileImg);
            }
            else
            {
                #region 参数设置
                //水印判断
                if (DTRequest.GetQueryString("IsWater") == "1")
                {
                    isWater = true;
                }
                if (siteConfig.watermarktype > 0)
                {
                    isWater = true;
                }
                //缩略图判断
                if (DTRequest.GetQueryString("IsThumbnail") == "1")
                {
                    isThumbnail = true;
                }
                //压缩判断
                if (DTRequest.GetQueryString("compress") == "0")
                {
                    isCompress = false;
                }
                //解析缩略图尺寸
                int thumbnailWidth = siteConfig.thumbnailwidth;
                int thumbnailHeight = siteConfig.thumbnailheight;
                string thumbnailMode = siteConfig.thumbnailmode;
                if (_channel_id > 0)
                {
                    var model = new BLL.site_channel().GetCaCheModel(_channel_id);
                    if (model != null)
                    {
                        Model.site_channel_thum t = null;
                        if (DTRequest.GetQueryString("cover") == "1")
                        {
                            t = model.channel_thums.Find(p => p.class_id == 1 && p.is_lock == 1);
                            if (t != null)
                            {
                                isCover = true;
                            }
                        }
                        else
                        {
                            //缩略图
                            t = model.channel_thums.Find(p => p.class_id == 2 && p.is_lock == 1);
                        }
                        if (t != null)
                        {
                            switch (t.typeid)
                            {
                                case 1:
                                    thumbnailMode = "HWB";
                                    break;
                                case 2:
                                    thumbnailMode = "HW";
                                    break;
                                case 3:
                                    thumbnailMode = "W";
                                    break;
                                case 4:
                                    thumbnailMode = "H";
                                    break;
                                default:
                                    thumbnailMode = "Cut";
                                    break;
                            }
                            thumbnailWidth = t.width;
                            thumbnailHeight = t.height;
                        }
                    }
                }
                #endregion
                var msg = upLoad.FileSaveAs(upType, byteData, fileName, isThumbnail, isWater, isCompress, isCover, thumbnailWidth, thumbnailHeight, thumbnailMode, false, out string fileImg);
                //删除已存在的旧文件
                if (!string.IsNullOrEmpty(_delfile))
                {
                    upLoad.DeleteFile(_delfile);
                }
                //返回成功信息
                return msg;
            }
        }
        #endregion

        #region 分片上传
        /// <summary>
        /// 合并文件
        /// </summary>
        /// <param name="guid"></param>
        /// <param name="fileExt"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult MergeFiles(string guid, string fileExt, string path)
        {
            string folder = path = path.TrimEnd('/');
            path = folder.Substring(0, folder.LastIndexOf('/'));
            string root = Utils.GetMapPath(path);
            string sourcePath = Path.Combine(root, guid + "/");//源数据文件夹
            string newFileName = Utils.GetRamCode() + fileExt; //随机生成新的文件名
            string newFilePath = root + "/" + newFileName; //本地上传后的路径
            long byteData = 0;

            DirectoryInfo dicInfo = new DirectoryInfo(sourcePath);
            if (Directory.Exists(Path.GetDirectoryName(sourcePath)))
            {
                FileInfo[] files = dicInfo.GetFiles();
                foreach (FileInfo file in files.OrderBy(f => int.Parse(f.Name)))
                {
                    FileStream addFile = new FileStream(newFilePath, FileMode.Append, FileAccess.Write);
                    BinaryWriter AddWriter = new BinaryWriter(addFile);

                    //获得上传的分片数据流
                    Stream stream = file.Open(FileMode.Open);
                    byteData += file.Length;
                    BinaryReader TempReader = new BinaryReader(stream);
                    //将上传的分片追加到临时文件末尾
                    AddWriter.Write(TempReader.ReadBytes((int)stream.Length));
                    //关闭BinaryReader文件阅读器
                    TempReader.Close();
                    stream.Close();
                    AddWriter.Close();
                    addFile.Close();

                    TempReader.Dispose();
                    stream.Dispose();
                    AddWriter.Dispose();
                    addFile.Dispose();
                }
                FileHelper.DeleteDirectory(path + "/" + guid);
                return Json(new { status = 1, msg = "上传文件成功！", path = path + "/" + newFileName, thumb = "", size = byteData, ext = fileExt });
            }
            else
            {
                return Json(new { status = 0, msg = "上传过程中发生意外错误！" });
            }
        }
        #endregion

        #region 配置文件
        public JsonResult EditorConfig()
        {
            string savePath = siteConfig.webpath + siteConfig.filepath + (siteConfig.filesave > 1 ? "/{yyyy}{mm}/{dd}/" : "/{yyyy}{mm}{dd}/");
            return Json(new
            {
                //上传图片配置项
                imageActionName = "uploadimage",  //执行上传图片的action名称
                imageFieldName = "upfile",   //提交的图片表单名称
                imageMaxSize = siteConfig.imgsize * 1024,  //上传大小限制，单位B
                imageAllowFiles = siteConfig.imgextension.Split(',').Select(p => "." + p),   //上传图片格式显示
                imageCompressEnable = false,   //是否压缩图片,默认是true
                imageCompressBorder = 1600, //图片压缩最长边限制
                imageInsertAlign = "none",  //插入的图片浮动方式
                imageUrlPrefix = "",   //图片访问路径前缀
                imagePathFormat = savePath,  //上传保存路径
                //涂鸦图片上传配置项
                scrawlActionName = "uploadscrawl",   //执行上传涂鸦的action名称
                scrawlFieldName = "upfile",   //提交的图片表单名称
                scrawlPathFormat = savePath,   //上传保存路径
                scrawlMaxSize = siteConfig.imgsize * 1024,   //上传大小限制，单位B
                scrawlUrlPrefix = "",   //图片访问路径前缀
                scrawlInsertAlign = "none",
                //截图工具上传
                snapscreenActionName = "uploadimage", //执行上传截图的action名称
                snapscreenPathFormat = savePath,   //上传保存路径
                snapscreenUrlPrefix = "",   //图片访问路径前缀
                snapscreenInsertAlign = "none",   //插入的图片浮动方式
                                                  //抓取远程图片配置
                catcherLocalDomain = new string[] { "127.0.0.1", "localhost", "img.baidu.com" },
                catcherActionName = "catchimage",  //执行抓取远程图片的action名称
                catcherFieldName = "source",    //提交的图片列表表单名称
                catcherPathFormat = savePath,   //上传保存路径
                catcherUrlPrefix = "",    //图片访问路径前缀
                catcherMaxSize = siteConfig.imgsize * 1024,  //上传大小限制，单位B
                catcherAllowFiles = new string[] { ".png", ".jpg", ".jpeg", ".gif", ".bmp" },  //抓取图片格式显示
                                                                                               //上传视频配置
                videoActionName = "uploadvideo",  //上传视频的action名称
                videoFieldName = "upfile",   //提交的视频表单名称
                videoPathFormat = savePath,   //上传保存路径
                videoUrlPrefix = "",  //视频访问路径前缀
                videoMaxSize = siteConfig.videosize * 1024,    //上传大小限制，单位B
                videoAllowFiles = siteConfig.videoextension.Split(',').Select(p => "." + p),
                //上传附件配置
                fileActionName = "uploadfile",  //上传附件的action名称
                fileFieldName = "upfile",  //提交的附件表单名称
                filePathFormat = savePath,   //上传保存路径
                fileUrlPrefix = "",   //附件访问路径前缀
                fileMaxSize = siteConfig.attachsize * 1024,   //上传大小限制，单位B
                fileAllowFiles = siteConfig.videoextension.Split(',').Select(p => "." + p),
                //列出指定目录下的图片
                imageManagerActionName = "listimage",
                imageManagerListPath = "/",
                imageManagerListSize = 20,
                imageManagerUrlPrefix = "",
                imageManagerInsertAlign = "none",
                imageManagerAllowFiles = new string[] { ".png", ".jpg", ".jpeg", ".gif", ".bmp" },
                //列出指定目录下的文件
                fileManagerActionName = "listfile",
                fileManagerListPath = "/",
                fileManagerUrlPrefix = "",
                fileManagerListSize = 20,
                fileManagerAllowFiles = (siteConfig.imgextension + "," + siteConfig.attachextension + "," + siteConfig.videoextension).Split(',').Select(p => "." + p)
            });
        }
        #endregion

        /// <summary>
        /// 上传图片
        /// </summary>
        public JsonResult EditorUploadImage()
        {
            bool isWater = false; //默认不打水印
            if (DTRequest.GetQueryString("IsWater") == "1")
            {
                isWater = true;
            }
            if (siteConfig.watermarktype != 0)
            {
                isWater = true;
            }
            HttpPostedFileBase upFile = Request.Files["upfile"];
            return FileSave(upFile, "img", isWater, true);
        }

        /// <summary>
        /// 上传视频
        /// </summary>
        public JsonResult EditorUploadVideo()
        {
            HttpPostedFileBase upFile = Request.Files["upfile"];
            return FileSave(upFile, "video", false, false);
        }

        /// <summary>
        /// 上传附件
        /// </summary>
        public JsonResult EditorUploadFile()
        {
            HttpPostedFileBase upFile = Request.Files["upfile"];
            return FileSave(upFile, "file", false, false);
        }

        /// <summary>
        /// 上传涂鸦
        /// </summary>
        public JsonResult EditorUploadScrawl()
        {
            byte[] byteData = Convert.FromBase64String(Request["upfile"]);
            string fileName = "scrawl.png";
            //开始上传
            string remsg = JsonConvert.SerializeObject(new UpLoad().FileSaveAs("img", byteData, fileName, false, false, true, false, 0, 0, string.Empty, false, out string fileImg).Data);
            Dictionary<string, object> dic = JsonHelper.DataRowFromJSON(remsg);
            string status = dic["status"].ToString();
            string msg = dic["msg"].ToString();
            if (status == "0")
            {
                return showError(msg);
            }
            string filePath = dic["path"].ToString(); //取得上传后的路径
            return showSuccess(fileName, filePath); //输出成功提示
        }

        /// <summary>
        /// 浏览图片
        /// </summary>
        public JsonResult EditorListImage()
        {
            string fileTypes = ".gif,.jpg,.jpeg,.png,.bmp"; //允许浏览的文件扩展名
            return ListFileManager(fileTypes);
        }

        /// <summary>
        /// 浏览文件
        /// </summary>
        public JsonResult EditorListFile()
        {
            string fileTypes = ".png,.jpg,.jpeg,.gif,.bmp,.flv,.swf,.mkv,.avi,.rm,.rmvb,.mpeg,.mpg,.ogg,.ogv,.mov,.wmv,"
                + ".mp4,.webm,.mp3,.wav,.mid,.rar,.zip,.tar,.gz,.7z,.bz2,.cab,.iso,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt,.md,.xml"; //允许浏览的文件扩展名
            return ListFileManager(fileTypes);
        }

        /// <summary>
        /// 抓取远程图片
        /// </summary>
        public JsonResult EditorCatchImage()
        {
            if (siteConfig.fileremote == 0)
            {
                return Json(new { state = "未开启远程图片本地化！" });
            }
            string[] sourcesUriArr = Request.Form.GetValues("source[]");
            if (sourcesUriArr == null || sourcesUriArr.Length == 0)
            {
                return Json(new { state = "参数错误：没有指定抓取源！" });
            }
            UpLoad upLoad = new UpLoad(); //初始化上传类
            List<Hashtable> fileList = new List<Hashtable>(); //存储上传成功的文件列表
            foreach (string sourcesUri in sourcesUriArr)
            {
                var Data = upLoad.RemoteSaveAs(sourcesUri).Data;
                string remsg = JsonConvert.SerializeObject(Data, Formatting.Indented);
                Dictionary<string, object> dic = JsonHelper.DataRowFromJSON(remsg);
                //如果抓取成功则加入文件列表
                if (dic["status"].ToString() == "1")
                {
                    Hashtable hash = new Hashtable();
                    hash["state"] = "SUCCESS";
                    hash["source"] = sourcesUri;
                    hash["url"] = dic["path"].ToString();
                    fileList.Add(hash);
                }
            }
            return Json(new { state = "SUCCESS！", list = fileList });
        }

        #region 辅助工具方法===================================
        /// <summary>
        /// 统一保存文件
        /// </summary>
        public JsonResult FileSave(HttpPostedFileBase upFiles, string upType, bool isWater, bool isCompress)
        {
            if (upFiles == null)
            {
                return showError("请选择要上传文件！");
            }
            //获取文件信息
            string fileName = upFiles.FileName;
            byte[] byteData = FileHelper.ConvertStreamToByteBuffer(upFiles.InputStream); //获取文件流
            //开始上传
            string remsg = JsonConvert.SerializeObject(new UpLoad().FileSaveAs(upType, byteData, fileName, false, isWater, isCompress, false, 0, 0, string.Empty, false, out string fileImg).Data);
            Dictionary<string, object> dic = JsonHelper.DataRowFromJSON(remsg);
            string status = dic["status"].ToString();
            string msg = dic["msg"].ToString();
            if (status == "0")
            {
                return showError(msg);
            }
            string filePath = dic["path"].ToString(); //取得上传后的路径
            return showSuccess(fileName, filePath); //输出成功提示
        }

        /// <summary>
        /// 显示错误提示
        /// </summary>
        public JsonResult showError(string message)
        {
            return Json(new { state = message, error = message });
        }

        /// <summary>
        /// 显示成功提示
        /// </summary>
        public JsonResult showSuccess(string fileName, string filePath)
        {
            return Json(new { state = "SUCCESS", url = filePath, title = fileName, original = fileName });
        }

        /// <summary>
        /// 浏览目录文件
        /// </summary>
        public JsonResult ListFileManager(string fileTypes)
        {
            int Start = DTRequest.GetInt("start", 0); //开始索引
            int Size = DTRequest.GetInt("size", 20); //每页大小
            int Total = 0; //文件总数
            string State = "SUCCESS"; //状态，默认成功
            String[] FileList = null;
            Hashtable hash = new Hashtable();

            var buildingList = new List<String>();
            try
            {
                string filePath = null;
                string localPath = null;
                if (siteConfig.fileserver.Equals("domain"))
                {
                    filePath = "/";
                    localPath = siteConfig.domainpath;
                    if (!localPath.EndsWith("\\"))
                    {
                        localPath = localPath + "\\";
                    }
                }
                else
                {
                    filePath = siteConfig.webpath + siteConfig.filepath;
                    localPath = Utils.GetMapPath(filePath); //站点目录+上传目录
                }
                buildingList.AddRange(Directory.GetFiles(localPath, "*", SearchOption.AllDirectories)
                    .Where(x => fileTypes.Contains(Path.GetExtension(x).ToLower()))
                    .Select(x => filePath + x.Substring(localPath.Length).Replace("\\", "/")));
                Total = buildingList.Count;
                FileList = buildingList.OrderBy(x => x).Skip(Start).Take(Size).ToArray();
            }
            catch (UnauthorizedAccessException)
            {
                State = "文件系统权限不足";
            }
            catch (DirectoryNotFoundException)
            {
                State = "路径不存在";
            }
            catch (IOException)
            {
                State = "文件系统读取错误";
            }
            finally
            {
                string prefix = string.Empty;
                if (siteConfig.fileserver.Equals("domain"))
                {
                    prefix = siteConfig.domainbind;
                }
                hash["state"] = State;
                hash["list"] = FileList == null ? null : FileList.Select(x => new { url = prefix + x });
                hash["start"] = Start;
                hash["total"] = Total;
            }
            return Json(hash);
        }
        #endregion

        #region 返回操作是否成功
        /// <summary>
        /// 操作成功
        /// </summary>
        /// <returns></returns>
        public void IsYes(string msg)
        {
            Response.Write(JsonHelper.ObjectToJSON(new { status = 1, msg = msg }));
        }
        /// <summary>
        /// 操作失败
        /// </summary>
        /// <returns></returns>
        public void IsNo(string msg)
        {
            Response.Write(JsonHelper.ObjectToJSON(new { status = 0, msg = msg }));
        }
        #endregion
    }
}